package com.link.base.wechat.wxcard.util;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.link.base.base.member.model.GiftCardWx;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.cllog.LCLogger;
import com.link.base.wechat.basic.util.WeixinHttpUtil;
import com.link.base.wechat.basic.util.WxExceptionUtil;
import com.link.base.wechat.wxcard.model.ItemData;
import com.link.base.wechat.wxcard.model.Page;
import com.link.base.wechat.wxcard.model.PicItemData;
import com.link.base.wechat.wxcard.model.ThemeData;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.HttpRequestUtil;
import com.link.core.util.JsonUtil;
import com.link.core.util.StringUtils;

import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 卡券管理工具类
 *
 * @author lujiang
 * @date 2019/02/25 17:00
 */
public class WxCardUtil {

    /**
     * 创建微信卡卷
     */
    public static final String CARD_CREATE_URL = "https://api.weixin.qq.com/card/create?access_token=ACCESS_TOKEN";
    /**
     * 激活会员卡接口
     */
    public static final String ACTIVATE_URL = "https://api.weixin.qq.com/card/membercard/activateuserform/set?access_token=ACCESS_TOKEN";
    /**
     * 修改卡券
     */
    public static final String CARD_UPDATE_URL = "https://api.weixin.qq.com/card/update?access_token=ACCESS_TOKEN";
    /**
     * 删除卡券
     */
    public static final String CARD_DELETE_URL = "https://api.weixin.qq.com/card/delete?access_token=ACCESS_TOKEN";
    /**
     * 修改会员信息
     */
    public static final String UPDATE_MEMBER_INFO = "https://api.weixin.qq.com/card/membercard/updateuser?access_token=ACCESS_TOKEN";
    /**
     * 解密卡券code
     */
    public static final String DECRYPT_URL = "https://api.weixin.qq.com/card/code/decrypt?access_token=ACCESS_TOKEN";

    /**
     * 获取开卡组件参数
     */
    public static final String GET_EXTRA_DATA = "https://api.weixin.qq.com/card/membercard/activate/geturl?access_token=ACCESS_TOKEN";

    /**拉取会员信息（积分查询）接口*/
    public static final String GET_USER_INFO_URL = "https://api.weixin.qq.com/card/membercard/userinfo/get?access_token=ACCESS_TOKEN";

    /**
     * 卡券Code解码接口
     *
     * @author ouyangzhenqiang
     * @date 2019/03/12 16:47
     * @param accessToken 接口调用凭证
     * @param encryptCode 加密code
     */
    public static JSONObject codeDecrypt(String accessToken, String encryptCode) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new ServiceException("WXCARD-028");
        }
        if (StringUtils.isBlank(encryptCode)) {
            throw new ServiceException("WXCARD-029");
        }
        String url = DECRYPT_URL.replace("ACCESS_TOKEN", accessToken);
        JSONObject obj = new JSONObject();
        obj.put("encrypt_code", encryptCode);
        String content = obj.toJSONString();
        String resultStr = HttpRequestUtil.sendPost(url, content, null);
        return WxExceptionUtil.parse(resultStr);
    }

    /**
     * 创建卡券、修改卡券
     *
     * @author lujiang
     * @date 2019/02/25 19:52
     * @param accessToken 全局唯一接口调用凭据
     * @param rowStatus NEW OR UPDATE
     * @param cardJson    卡券JOSN
     */
    public static Map<String,Object> createWxCard(String accessToken,String rowStatus,String cardJson) throws Exception {
        Map<String,Object> map = new HashMap<>(8);
        if (StringUtils.isBlank(rowStatus)) {
            throw new ServiceException("WXCARD-030");
        }
        if (StringUtils.isBlank(cardJson)) {
            throw new ServiceException("WXCARD-031");
        }
        //2.请求服务url
        String requestUrl = "";
        String insert = "NEW";
        String update = "UPDATE";
        Map<String, Object> card = new HashMap<>(16);
        if (StringUtils.equals(rowStatus,insert)) {
            requestUrl = CARD_CREATE_URL.replace("ACCESS_TOKEN", accessToken);
        } else if (StringUtils.equals(rowStatus,update)) {
            requestUrl = CARD_UPDATE_URL.replace("ACCESS_TOKEN", accessToken);
        }
        // 发起请求
        JSONObject jsonObject = WeixinHttpUtil.httpRequest(requestUrl, "POST", cardJson);
        // 错误码key
        String errCode = "errcode";
        // 错误码value
        int result = 0;
        if (null == jsonObject) {
            result = 0;
        } else if (null != jsonObject && 0 != jsonObject.getInteger(errCode)) {
            String msg = "";
            if (StringUtils.equals(rowStatus,insert)) {
                msg = "新增卡券失败 errcode:" + jsonObject.getInteger(errCode)
                        + " errmsg:" + jsonObject.getString("errmsg");
                LCLogger.error().withMessageKey("createCard")
                        .withMessage(msg).flush();
            } else if (StringUtils.equals(rowStatus,update)) {
                msg = "修改卡券信息失败 errcode:" + jsonObject.getInteger(errCode)
                        + " errmsg:" + jsonObject.getString("errmsg");
                LCLogger.error().withMessageKey("updateCardInfo")
                        .withMessage(msg).flush();
            }
            throw new Exception(msg);
        }
        // 请求成功
        if (null != jsonObject && 0 == jsonObject.getInteger(errCode)) {
            result = 1;
            if (StringUtils.equals(rowStatus,insert)) {
                map.put("card_id",jsonObject.getString("card_id"));
            }
        }
        map.put("result",result);
        return map;
    }

    /**
     * 删除卡券
     *
     * @author lujiang
     * @date  2019/02/25 20:20
     * @param accessToken  全局唯一接口调用凭据
     * @param cardId 卡券id
     * @return 1成功 0失败
     * @throws Exception
     */
    public static int deleteCard(String accessToken,String cardId) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new ServiceException("WXCARD-028");
        }
        if (StringUtils.isBlank(cardId)) {
            throw new ServiceException("WXCARD-032");
        }
        String deleteUrl = CARD_DELETE_URL.replace("ACCESS_TOKEN", accessToken);
        Map<String,Object> dataMap = new HashMap<>(4);
        dataMap.put("card_id",cardId);
        String cardJson = JsonUtil.toString(dataMap);
        JSONObject jsonObject = WeixinHttpUtil.httpRequest(deleteUrl, "POST", cardJson);
        WxExceptionUtil.parse(jsonObject.toJSONString());
        int result = 1;
        return result;
    }

    /**
     * 激活卡券
     *
     * @author lujiang
     * @date  2019/02/25 20:20
     * @param accessToken  全局唯一接口调用凭据
     * @param datajson json字符串
     * @return 1成功 0失败
     * @throws Exception
     */
    public static int activeCard(String accessToken,String datajson) throws Exception {
        String url = ACTIVATE_URL.replace("ACCESS_TOKEN", accessToken);
        JSONObject jsonObject = WeixinHttpUtil.httpRequest(url, "POST", datajson);
        WxExceptionUtil.parse(jsonObject.toJSONString());
        int result = 1;
        return result;
    }

    /**
     * 修改会员信息
     *
     * @author lujiang
     * @date  2019/02/25 20:20
     * @param accessToken  全局唯一接口调用凭据
     * @param datajson json字符串
     * @return 1成功 0失败
     * @throws Exception
     */
    public static int updateMemberInfo(String accessToken,String datajson) throws Exception {
        String url = UPDATE_MEMBER_INFO.replace("ACCESS_TOKEN", accessToken);
        JSONObject jsonObject = WeixinHttpUtil.httpRequest(url, "POST", datajson);
        WxExceptionUtil.parse(jsonObject.toJSONString());
        int result = 1;
        return result;
    }

    /**
     * 创建-礼品卡货架接口
     *
     * @author lujiang
     * @date 2019/03/01 19:20
     * @param accessToken  全局唯一接口调用凭据
     * @param page  礼品卡货架对象
     * @param rowStatus 创建或者修改
     */
    public static Map<String,Object> upsertGiftCardPage(String accessToken, Page page, String rowStatus) throws Exception {
        Map<String,Object> map = new HashMap<>(16);
        // 校验必输性
        checkGiftCardPageData(accessToken,page);
        Map<String,Object> data = new HashMap<>();
        data.put("page",page);
        // 驼峰转下划线
        String pageJson = WxCardUtil.getJsonData(data);
        if (StringUtils.equals(rowStatus,"NEW")) {
            String url = "https://api.weixin.qq.com/card/giftcard/page/add?access_token=" + accessToken;
            JSONObject jsonObject = WeixinHttpUtil.httpRequest(url, "POST", pageJson);
            WxExceptionUtil.parse(jsonObject.toJSONString());
            map.put("page_id",jsonObject.getString("page_id"));
        } else if (StringUtils.equals(rowStatus,"UPDATE")) {
            String url = "https://api.weixin.qq.com/card/giftcard/page/update?access_token=" + accessToken;
            JSONObject jsonObject = WeixinHttpUtil.httpRequest(url, "POST", pageJson);
            WxExceptionUtil.parse(jsonObject.toJSONString());
            map.put("errmsg",jsonObject.getString("errmsg"));
        }
        map.put("result","1");
        return map;
    }

    /**
     * 校验礼品卡货架信息必输性
     *
     * @author lujiang
     * @date 2019/03/01 19:20
     * @param access_token 全局唯一凭证
     * @param page
     * @throws Exception
     */
    private static void checkGiftCardPageData(String access_token, Page page) throws Exception {
        if (null == page) {
            throw new ServiceException("WXCARD-033");
        }
        if (StringUtils.isBlank(access_token)) {
            throw new ServiceException("WXCARD-034");
        }
        if (StringUtils.isBlank(page.getPageTitle())) {
            throw new ServiceException("WXCARD-035");
        }
        if (StringUtils.isBlank(page.getBannerPicUrl())) {
            throw new ServiceException("WXCARD-036");
        }
        if (null == page.getThemeList()) {
            throw new ServiceException("WXCARD-037");
        } else {
            if (page.getThemeList().size() < 1) {
                throw new ServiceException("WXCARD-038");
            }
            for (ThemeData themeData : page.getThemeList()) {
                if (StringUtils.isBlank(themeData.getThemePicUrl())) {
                    throw new ServiceException("WXCARD-039");
                }
                if (StringUtils.isBlank(themeData.getTitle())) {
                    throw new ServiceException("WXCARD-040");
                }
                if (StringUtils.isBlank(themeData.getTitleColor())) {
                    throw new ServiceException("WXCARD-041");
                }
                if (StringUtils.isBlank(themeData.getCategoryIndex() + "")) {
                    throw new ServiceException("WXCARD-042");
                }
                if (null == themeData.getItemList()) {
                    throw new ServiceException("WXCARD-043");
                } else {
                    for (ItemData itemData : themeData.getItemList()) {
                        if (StringUtils.isBlank(itemData.getCardId())) {
                            throw new ServiceException("WXCARD-044");
                        }
                    }
                }
                if (null == themeData.getPicItemList()) {
                    throw new ServiceException("WXCARD-045");
                } else {
                    for (PicItemData picItemData : themeData.getPicItemList()) {
                        if (StringUtils.isBlank(picItemData.getBackgroundPicUrl())) {
                            throw new ServiceException("WXCARD-046");
                        }
                        if (StringUtils.isBlank(picItemData.getDefaultGiftingMsg())) {
                            throw new ServiceException("WXCARD-047");
                        }
                    }
                }
            }
        }
        if (StringUtils.isBlank(page.getAddress())) {
            throw new ServiceException("WXCARD-048");
        }
        if (StringUtils.isBlank(page.getServicePhone())) {
            throw new ServiceException("WXCARD-049");
        }
        if (StringUtils.isBlank(page.getBizDescription())) {
            throw new ServiceException("WXCARD-050");
        }
        if (null == page.getCell_1() && null == page.getCell_2()) {
            throw new ServiceException("WXCARD-051");
        }
        if (null != page.getCell_1()) {
            if (StringUtils.isBlank(page.getCell_1().getTitle())) {
                throw new ServiceException("WXCARD-052");
            }
            if (StringUtils.isBlank(page.getCell_1().getUrl())) {
                throw new ServiceException("WXCARD-053");
            }
        }
        if (null != page.getCell_2()) {
            if (StringUtils.isBlank(page.getCell_2().getTitle())) {
                throw new ServiceException("WXCARD-054");
            }
            if (StringUtils.isBlank(page.getCell_2().getUrl())) {
                throw new ServiceException("WXCARD-055");
            }
        }
    }

    /**
     * 时间戳转换成日期格式字符串
     *
     * @author lujiang
     * @date 2019-03-01 18：00
     * @param seconds 精确到秒的字符串
     * @param format formatStr
     * @return
     */
    public static String timeStampDate(String seconds,String format) {
        if (seconds == null || seconds.isEmpty() || seconds.equals("null")) {
            return "";
        }
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds + "000")));
    }

    /**
     * 日期格式字符串转换成时间戳
     *
     * @author lujiang
     * @date 2019-03-01 18：00
     * @param date_str 字符串日期
     * @param format formatStr
     * @return
     */
    public static String date2TimeStamp(String date_str,String format) {
        try {
            if (format == null || format.isEmpty()) {
                format = "yyyy-MM-dd HH:mm:ss";
            }
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return String.valueOf(sdf.parse(date_str).getTime() / 1000);
        } catch (Exception e) {
            LCLogger.withException(e.getMessage());
        }
        return "";
    }

    /**
     * 货架打通小程序
     *
     * @author lujiang
     * @date 2019-03-04 18：00
     * @param giftCardWx
     * @param access_token 全局唯一凭证
     * @return
     * @throws Exception
     */
    public static Map<String,Object> setGiftCardWxa(GiftCardWx giftCardWx, String access_token) throws Exception {
        Map<String,Object> map = new HashMap<>(8);
        if (StringUtils.isBlank(access_token)) {
            throw new ServiceException("WXCARD-056");
        }
        if (null == giftCardWx) {
            throw new ServiceException("WXCARD-057");
        } else  if (StringUtils.isBlank(giftCardWx.getPageId())) {
            throw new ServiceException("WXCARD-058");
        } else if (StringUtils.isBlank(giftCardWx.getWxaAppid())) {
            throw new ServiceException("WXCARD-059");
        }
        map.put("wxa_appid",giftCardWx.getWxaAppid());
        map.put("page_id",giftCardWx.getPageId());
        String jsonData = JsonUtil.toString(map);
        String requestUrl = "https://api.weixin.qq.com/card/giftcard/wxa/set?access_token=" + access_token;
        JSONObject jsonObject = WeixinHttpUtil.httpRequest(requestUrl, "POST", jsonData);
        WxExceptionUtil.parse(jsonObject.toJSONString());
        map.put("errmsg",jsonObject.getString("errmsg"));
        return map;
    }

    /**
     * 驼峰数据转为下划线
     *
     * @author 路江
     * @date 2019-12-26
     * @param object 数据对象
     * @return
     * @throws Exception
     */
    public static String getJsonData(Object object) throws Exception {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        Gson gson = gsonBuilder.create();
        String jsonData = gson.toJson(object);
        return  jsonData;
    }

    /**
     * 获取开卡组件参数
     *
     * @author KuangRuifeng
     * @date 2019年4月30日10:55
     * @param cardId      卡券id
     * @param outerStr    渠道
     * @param accessToken token
     */
    public static Map<String, String> getExtraData(String cardId, String outerStr, String accessToken) throws Exception {
        if (StringUtils.isBlank(cardId)) {
            throw new Exception("cardId不能为空！");
        }
        if (StringUtils.isBlank(accessToken)) {
            throw new Exception("accessToken不能为空！");
        }
        String requestUrl = GET_EXTRA_DATA.replace("ACCESS_TOKEN", accessToken);
        JSONObject obj = new JSONObject();
        obj.put("card_id", cardId);
        obj.put("outer_str", outerStr);
        String content = obj.toJSONString();
        JSONObject result =  WxExceptionUtil.parse(HttpRequestUtil.sendPost(requestUrl, content, null));
        String resultUrl = result.getString("url");
        // 解析url获得参数
        String paramStr = resultUrl.substring(resultUrl.indexOf("encrypt_card_id=") + "encrypt_card_id=".length(), resultUrl.indexOf("#"));
        String[] urlParam = paramStr.split("&");
        String encryptCardId = "";
        String outStr = "";
        String biz = "";
        Map<String, String> map = new HashMap<>(3);
        // 长度大于2，带有outerStr
        int hasOutStrLength = 2;
        if (urlParam.length > hasOutStrLength) {
            encryptCardId = urlParam[0];
            outStr = urlParam[1].split("=")[1];
            biz = urlParam[2].split("=")[1];
        } else {
            // 不带有outerStr
            encryptCardId = urlParam[0];
            biz = urlParam[1].split("=")[1];
        }
        map.put("encryptCardId", URLDecoder.decode(encryptCardId, "UTF-8"));
        map.put("biz", URLDecoder.decode(biz, "UTF-8"));
        map.put("outerStr", URLDecoder.decode(outStr, "UTF-8"));
        return map;
    }

    /**
     * 拉取会员信息（积分查询）接口
     *
     * @author 安小波
     * @date 2020/1/9 19:43
     * @param accessToken 公众号accessToken
     * @param code 会员卡code
     * @param cardId 卡券card_id
     */
    public static JSONObject getUserInfo(String accessToken, String code, String cardId) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        if (StringUtils.isBlank(code)) {
            throw new BasicServiceException("code不能为空！");
        }
        if (StringUtils.isBlank(cardId)) {
            throw new BasicServiceException("cardId不能为空！");
        }
        String url = GET_USER_INFO_URL.replace("ACCESS_TOKEN", accessToken);
        JSONObject param = new JSONObject();
        param.put("card_id", cardId);
        param.put("code", code);
        LCLogger.info().withMessageKey("getUserInfo")
                .withMessage("accessToken==" + accessToken + ";param==" + param).flush();
        JSONObject jsonObject = WeixinHttpUtil.httpRequest(url, "POST", param.toJSONString());
        LCLogger.info().withMessageKey("getUserInfo")
                .withMessage("响应结果===" + jsonObject.toJSONString()).flush();
        return jsonObject;
    }
}
